from enum import Enum

class UserState(Enum):
    IDLE = 0
    RECO = 1
    SRCH = 2
    SELECT = 3
    WATCH = 4
    PAUSE = 5
    EXIT = 6

class WatchEvent:
    def __init__(self, uid: int, vid: int, vdx: int) -> None:
        self.uid = uid
        self.vid = vid
        self.vdx = vdx

class Slice:
    def __init__(self, start, stop) -> None:
        assert start >= 0
        assert start <= stop
        self.start = start
        self.stop = stop

    def __contains__(self, other) -> bool:
        return self.start <= other.start and self.stop >= other.stop

    def __eq__(self, value: object) -> bool:
        return self.start == value.start and self.stop == value.stop

    def __len__(self) -> int:
        return self.stop - self.start + 1

    def __str__(self) -> str:
        return f"[{self.start}, {self.stop}]"

class Region(Enum):
    Invalid     = -1
    Static      = 0
    Dynamic     = 1
    Maintain    = 2
    Victim      = 3

class Content:
    def __init__(self, id: int, slice: Slice, region: Region = Region.Invalid, expire: int = 0, freq: int = -1) -> None:
        # Video ID
        self.vid = id
        # Video Slices
        self.slice = slice
        # Cache Region
        self.region = region
        # Expire Time
        self.expire = expire
        # Frequency
        self.freq = freq # Used for S3FIFO

    def __lt__(self, other) -> bool:
        if len(self.slice) != len(other.slice):
            return len(self.slice) < len(other.slice)
        return self.vid < other.id

    def __eq__(self, value: object) -> bool:
        return self.vid == value.id and self.slice == value.slices

    def __str__(self) -> str:
        return f"Content({self.vid}, {self.slice})"

    def __repr__(self) -> str:
        return self.__str__()
    
class KV:
    def __init__(self, vid: int, val: float, typ: str):
        self.vid = vid
        self.val = val
        self.typ = typ
    
    def __eq__(self, other):
        return self.vid == other.vid
    
    def __lt__(self, other):
        # 按照 typ, val, vid 的顺序排序
        if self.typ != other.typ:
            return self.typ > other.typ
        if self.val != other.val:
            return self.val < other.val
        return self.vid < other.vid
    
    def __str__(self):
        return f"({self.vid}, {self.val}, {self.typ})"
    
    def __repr__(self):
        return self.__str__()
